﻿using Fabrication.Tests.TestClasses;
using NUnit.Framework;

namespace Fabrication.Tests
{
    [TestFixture]
    public class string_rules
    {
        [Test]
        public void should_use_numeric_range_converted_to_string()
        {
            var builtItem = new FabricationScope().Setup<SinglePropertyClass<string>>()
                            .For(x => x.Value).UseRange(100, 101)
                            .Generate();

            Assert.That(builtItem.Value == "100" || builtItem.Value == "101");
        }

        [Test]
        public void should_generate_random_given_name_when_specified()
        {
            var builtItem = new FabricationScope().Setup<SinglePropertyClass<string>>()
                            .For(x => x.Value).GenerateGivenName()
                            .Generate();

            Assert.That(builtItem.Value, Is.Not.Empty.And.Not.ContainsSubstring("Value"));
        }

        [Test]
        public void should_generate_random_last_name_when_specified()
        {
            var builtItem = new FabricationScope().Setup<SinglePropertyClass<string>>()
                            .For(x => x.Value).GenerateLastName()
                            .Generate();

            Assert.That(builtItem.Value, Is.Not.Empty.And.Not.ContainsSubstring("Value"));
        }

        [Test]
        public void should_generate_random_full_name_when_specified()
        {
            var builtItem = new FabricationScope().Setup<SinglePropertyClass<string>>()
                            .For(x => x.Value).GenerateFullName()
                            .Generate();

            Assert.That(builtItem.Value, Is.Not.Empty.And.Not.ContainsSubstring("Value"));
        }

        [Test]
        public void should_generate_random_email_address_when_specified()
        {
            var builtItem = new FabricationScope().Setup<SinglePropertyClass<string>>()
                            .For(x => x.Value).GenerateEmailAddress()
                            .Generate();

            Assert.That(builtItem.Value, Is.Not.Empty.And.Not.ContainsSubstring("Value"));
        }

        [Test]
        public void should_generate_random_user_name_when_specified()
        {
            var builtItem = new FabricationScope().Setup<SinglePropertyClass<string>>()
                            .For(x => x.Value).GenerateUserName()
                            .Generate();

            Assert.That(builtItem.Value, Is.Not.Empty.And.Not.ContainsSubstring("Value"));
        }

        [Test]
        public void should_generate_random_country_when_specified()
        {
            var builtItem = new FabricationScope().Setup<SinglePropertyClass<string>>()
                            .For(x => x.Value).GenerateCountry()
                            .Generate();

            Assert.That(builtItem.Value, Is.Not.Empty.And.Not.ContainsSubstring("Value"));
        }

        [Test]
        public void should_generate_standard_lorem_ipsum_text_when_specified()
        {
            var builtItem = new FabricationScope().Setup<SinglePropertyClass<string>>()
                            .For(x => x.Value).GenerateLoremIpsum()
                            .Generate();

            Assert.That(builtItem.Value, Is.Not.Empty.And.StartsWith("Lorem ipsum"));
        }

        [Test]
        public void should_generate_lorem_ipsum_text_of_specified_length()
        {
            var builtItem = new FabricationScope().Setup<SinglePropertyClass<string>>()
                            .For(x => x.Value).GenerateLoremIpsum(100)
                            .Generate();

            Assert.That(builtItem.Value, Has.Length.EqualTo(100).And.StartsWith("Lorem ipsum"));
        }

        [Test]
        public void should_generate_random_name_for_conventional_first_name_properties()
        {
            var builtItem = new FabricationScope().Generate<NamesConventionClass>();

            Assert.That(builtItem.FirstName, Is.Not.Empty.And.Not.ContainsSubstring("FirstName"));
            Assert.That(builtItem.GivenName, Is.Not.Empty.And.Not.ContainsSubstring("GivenName"));
        }

        [Test]
        public void should_generate_random_name_for_conventional_last_name_properties()
        {
            var builtItem = new FabricationScope().Generate<NamesConventionClass>();

            Assert.That(builtItem.LastName, Is.Not.Empty.And.Not.ContainsSubstring("LastName"));
            Assert.That(builtItem.Surname, Is.Not.Empty.And.Not.ContainsSubstring("Surname"));
        }

        [Test]
        public void should_generate_random_name_for_conventional_full_name_properties()
        {
            var builtItem = new FabricationScope().Generate<NamesConventionClass>();

            Assert.That(builtItem.FullName, Is.Not.Empty.And.Not.ContainsSubstring("FullName"));
        }

        [Test]
        public void should_generate_random_email_address_for_conventional_email_properties()
        {
            var builtItem = new FabricationScope().Generate<EmailConventionClass>();

            Assert.That(builtItem.Email, Is.Not.Empty.And.Not.ContainsSubstring("Email"));
            Assert.That(builtItem.EmailAddress, Is.Not.Empty.And.Not.ContainsSubstring("EmailAddress"));
        }

        [Test]
        public void should_generate_random_user_name_for_conventional_user_name_properties()
        {
            var builtItem = new FabricationScope().Generate<UserNameConventionClass>();

            Assert.That(builtItem.UserName, Is.Not.Empty.And.Not.ContainsSubstring("UserName"));
        }

        [Test]
        public void should_generate_random_country_for_conventional_country_properties()
        {
            var builtItem = new FabricationScope().Generate<CountryConventionClass>();

            Assert.That(builtItem.Country, Is.Not.Empty.And.Not.ContainsSubstring("Country"));
        }

        [Test]
        public void should_generate_random_phone_number_for_conventional_phone_properties()
        {
            var builtItem = new FabricationScope().Generate<PhoneConventionClass>();

            Assert.That(builtItem.Phone, Is.Not.Empty.And.Not.ContainsSubstring("Phone"));
            Assert.That(builtItem.PhoneNumber, Is.Not.Empty.And.Not.ContainsSubstring("PhoneNumber"));
            Assert.That(builtItem.Mobile, Is.Not.Empty.And.Not.ContainsSubstring("Mobile"));
            Assert.That(builtItem.MobileNumber, Is.Not.Empty.And.Not.ContainsSubstring("MobileNumber"));
        }

        [Test]
        public void should_link_value_to_other_property_when_specified()
        {
            var builtItem = new FabricationScope().Setup<DoublePropertyClass<string>>()
                            .For(x => x.FirstValue).GenerateFullName()
                            .Link(x => x.SecondValue).To(x => x.FirstValue)
                            .Generate();

            Assert.That(builtItem.SecondValue, Is.EqualTo(builtItem.FirstValue));
        }

        [Test]
        public void should_ignore_rule_order_when_linking_within_item()
        {
            var builtItem = new FabricationScope().Setup<DoublePropertyClass<string>>()
                            .Link(x => x.SecondValue).To(x => x.FirstValue)
                            .For(x => x.FirstValue).GenerateFullName()
                            .Generate();

            Assert.That(builtItem.SecondValue, Is.EqualTo(builtItem.FirstValue));
        }

        [Test]
        public void should_ignore_property_order_when_linking_within_item()
        {
            var builtItem = new FabricationScope().Setup<DoublePropertyClass<string>>()
                            .For(x => x.SecondValue).GenerateFullName()
                            .Link(x => x.FirstValue).To(x => x.SecondValue)
                            .Generate();

            Assert.That(builtItem.FirstValue, Is.EqualTo(builtItem.SecondValue));
        }

        [Test]
        public void should_generate_random_street_name_when_specified()
        {
            var builtItem = new FabricationScope().Setup<SinglePropertyClass<string>>()
                            .For(x => x.Value).GenerateStreetName()
                            .Generate();

            Assert.That(builtItem.Value, Is.Not.Empty.And.Not.ContainsSubstring("Value"));
        }

        [Test]
        public void should_generate_random_street_type_when_specified()
        {
            var builtItem = new FabricationScope().Setup<SinglePropertyClass<string>>()
                            .For(x => x.Value).GenerateStreetType()
                            .Generate();

            Assert.That(builtItem.Value, Is.Not.Empty.And.Not.ContainsSubstring("Value"));
        }

        [Test]
        public void should_generate_random_street_when_specified()
        {
            var builtItem = new FabricationScope().Setup<SinglePropertyClass<string>>()
                            .For(x => x.Value).GenerateStreet()
                            .Generate();

            Assert.That(builtItem.Value, Is.Not.Empty.And.Not.ContainsSubstring("Value"));
        }

        [Test]
        public void should_generate_random_address_when_specified()
        {
            var builtItem = new FabricationScope().Setup<SinglePropertyClass<string>>()
                            .For(x => x.Value).GenerateAddress()
                            .Generate();

            Assert.That(builtItem.Value, Is.Not.Empty.And.Not.ContainsSubstring("Value"));
        }

        [Test]
        public void should_generate_random_phone_number_when_specified()
        {
            var builtItem = new FabricationScope().Setup<SinglePropertyClass<string>>()
                            .For(x => x.Value).GeneratePhoneNumber()
                            .Generate();

            Assert.That(builtItem.Value, Is.Not.Empty.And.Not.ContainsSubstring("Value"));
        }
    }
}
